package com.bf.electroplating.util;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bf.electroplating.login.UserContext;
import com.bf.electroplating.login.UserDetail;
import com.bf.electroplating.pojo.entity.ControlProblemFinding;
import com.bf.electroplating.pojo.entity.ControlProblemRenovate;
import com.bf.electroplating.pojo.entity.InspectionTask;
import com.bf.electroplating.pojo.enums.InspectionTaskStatusEnum;
import com.bf.electroplating.pojo.enums.RectificationStatusEnum;
import com.bf.electroplating.pojo.vo.SelectVo;
import com.bf.electroplating.service.ControlProblemFindingService;
import com.bf.electroplating.service.ControlProblemRenovateService;
import com.bf.electroplating.service.InspectionTaskService;
import com.bf.electroplating.service.PubParamDictionaryService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Component
@Slf4j
public class ScheduledTaskUtils {

    @Resource
    private InspectionTaskService inspectionTaskService;
    @Resource
    private PubParamDictionaryService pubParamService;
    @Resource
    private ControlProblemFindingService controlProblemFindingService;
    @Resource
    private ControlProblemRenovateService controlProblemRenovateService;

    // 每5分钟执行一次（cron表达式：秒 分 时 日 月 周）
    @Scheduled(cron = "0 */3 * * * ?")
    public void executeTask() {
        UserDetail userDetail = new UserDetail();
        userDetail.setUserAccountName("sys_auto_task");
        userDetail.setParkFunctionIds(pubParamService.getParamList("PARK").getData().stream().map(SelectVo::getId).toList());
        UserContext.setUser(userDetail);

        List<InspectionTask> taskList = inspectionTaskService.list(new LambdaQueryWrapper<InspectionTask>()
                .or(task -> task
                        .ne(InspectionTask::getStatus, InspectionTaskStatusEnum.ING_OVER.getCode())
                        .ne(InspectionTask::getStatus, InspectionTaskStatusEnum.YET.getCode())
                        .ne(InspectionTask::getStatus, InspectionTaskStatusEnum.YET_OVER.getCode())
                        .ne(InspectionTask::getStatus, InspectionTaskStatusEnum.OVER.getCode())));
        for (InspectionTask task : taskList) {
            if (task.getStatus().equals(InspectionTaskStatusEnum.NO_START.getCode()) && isNotSameDay(task.getStartTime(), new Date()) && task.getStartTime().before(new Date())) {
                task.setStatus(InspectionTaskStatusEnum.AWAIT.getCode());
                log.info("任务开始时间已到，任务ID：{}，任务原状态：NO_START，现状态：AWAIT", task.getId());
                inspectionTaskService.updateById(task);
            }
            if (task.getStatus().equals(InspectionTaskStatusEnum.AWAIT.getCode()) && isNotSameDay(task.getEndTime(), new Date()) && task.getEndTime().before(new Date())) {
                task.setStatus(InspectionTaskStatusEnum.OVER.getCode());
                log.info("任务结束时间已到，任务ID：{}，任务原状态：AWAIT，现状态：OVER", task.getId());
                inspectionTaskService.updateById(task);
            }
            if (task.getStatus().equals(InspectionTaskStatusEnum.ING.getCode()) && isNotSameDay(task.getEndTime(), new Date()) && task.getEndTime().before(new Date())) {
                task.setStatus(InspectionTaskStatusEnum.ING_OVER.getCode());
                log.info("任务结束时间已到，任务ID：{}，任务原状态：ING，现状态：ING_OVER", task.getId());
                inspectionTaskService.updateById(task);
            }
        }
        UserContext.clear();
    }

    @Scheduled(cron = "0 */3 * * * ?")
    public void problemTask() {
        UserDetail userDetail = new UserDetail();
        userDetail.setUserAccountName("sys_auto_task");
        userDetail.setParkFunctionIds(pubParamService.getParamList("PARK").getData().stream().map(SelectVo::getId).toList());
        UserContext.setUser(userDetail);
        List<ControlProblemFinding> problemFindings = controlProblemFindingService.list(new LambdaQueryWrapper<ControlProblemFinding>()
                .eq(ControlProblemFinding::getRectificationStatus, RectificationStatusEnum.AWAIT.getCode()));
        for (ControlProblemFinding problemFinding : problemFindings) {

            if (isNotSameDay(problemFinding.getPlanCompletionTime(), new Date()) && problemFinding.getPlanCompletionTime().before(new Date())) {
                problemFinding.setRectificationStatus(RectificationStatusEnum.AWAIT_OVER.getCode());
                controlProblemFindingService.updateById(problemFinding);
            }
        }
        List<ControlProblemRenovate> list = controlProblemRenovateService.list(new LambdaQueryWrapper<ControlProblemRenovate>()
                .eq(ControlProblemRenovate::getRectificationStatus, RectificationStatusEnum.AWAIT.getCode()));
        for (ControlProblemRenovate problemRenovate : list) {
            if (isNotSameDay(problemRenovate.getTimeLimit(), new Date())&& problemRenovate.getTimeLimit().before(new Date())) {
                problemRenovate.setRectificationStatus(RectificationStatusEnum.AWAIT_OVER.getCode());
                controlProblemRenovateService.updateById(problemRenovate);
            }
        }
        UserContext.clear();
    }

    private boolean isNotSameDay(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();
        cal1.setTime(date1);
        cal2.setTime(date2);

        return cal1.get(Calendar.YEAR) != cal2.get(Calendar.YEAR) ||
                cal1.get(Calendar.MONTH) != cal2.get(Calendar.MONTH) ||
                cal1.get(Calendar.DAY_OF_MONTH) != cal2.get(Calendar.DAY_OF_MONTH);
    }

}
